/*
 *  $Id: Abstract.cs 1233 2010-12-18 17:54:48Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System.Collections.Generic;

namespace Ragima {
    /// <summary>
    /// Предикат проверки возможности цели определенного типа.
    /// </summary>
    /// <param name="request">Запрос цели.</param>
    /// <param name="obj">Объект цели.</param>
    /// <returns>Допустима ли данная цель.</returns>
    public delegate bool TargetPredicate<T>(TargetRequest request, T obj);

    /// <summary>
    /// Абстрактный тип цели (конкретные цели должны давать его наследники).
    /// </summary>
    public abstract class TargetType {
        private Languages.Phrase _notice;
        private TargetRequest _request;

        public TargetType() {
            _notice = null;
        }
        public TargetType(Languages.Phrase notice) {
            _notice = notice;
        }

        /// <summary>
        /// Фраза - подсказка цели.
        /// </summary>
        public Languages.Phrase Notice {
            get { return _notice; }
            protected set { _notice = value; }
        }
        /// <summary>
        /// Текст - подсказка цели.
        /// </summary>
        public string NoticeText {
            get { return _notice != null ? _notice.GetText() : string.Empty; }
        }

        /// <summary>
        /// Данные запроса цели.
        /// </summary>
        public TargetRequest Request {
            get { return _request; }
        }

        /// <summary>
        /// Этот тип цели подразумевает выбор одной конкретной цели.
        /// </summary>
        public virtual bool IsRealTarget {
            get { return false; }
        }

        /// <summary>
        /// Инициализирует цель.
        /// </summary>
        public virtual void Initialize(TargetRequest request) {
            _request = request;
        }

        /// <summary>
        /// Отменяет выбор цели.
        /// </summary>
        public virtual void Cancel() {
            if (Request != null)
                Request.Player.Game.RestoreSelection(Request.Player);
        }

        /// <summary>
        /// Автоматический выбор целевой вкладки.
        /// </summary>
        public void AutoSelectTab() {
            if (Application.Config.Interface.AutoTargetTab && Request != null)
                AutoSelectTab(Request.Player);
        }
        /// <summary>
        /// Автоматический выбор целевой вкладки.
        /// </summary>
        protected virtual void AutoSelectTab(Player player) {
        }

        /// <summary>
        /// Проверяет наличие целей.
        /// </summary>
        /// <param name="player">Игрок, для которого проверяются цели.</param>
        /// <returns>true, если цели есть.</returns>
        public virtual bool HasTargets(AbstractObject caster) {
            return GetCount(caster) > 0;
        }

        /// <summary>
        /// Получает число возможных целей.
        /// </summary>
        /// <param name="player">Игрок, для которого проверяются цели.</param>
        /// <returns>Число целей.</returns>
        public virtual int GetCount(AbstractObject caster) {
            return 0;
        }

        /// <summary>
        /// Получает список регионов, создаваемых целью.
        /// </summary>
        /// <returns>Список регионов.</returns>
        public virtual IEnumerable<Region> GetRegions() {
            yield break;
        }

        /// <summary>
        /// Обрабатывает клик по созданному региону.
        /// </summary>
        /// <param name="region">Регион, по которому кликнули.</param>
        public virtual void ClickRegion(Region region) {
            UseAction(region);
        }

        /// <summary>
        /// Проверяет, является ли регион подходящим для цели.
        /// </summary>
        /// <param name="region">Проверяемый регион<./param>
        /// <returns>true, если регион подходит для цели.</returns>
        public virtual bool AcceptRegion(Region region) {
            return false;
        }

        /// <summary>
        /// Обрабатывает клик по подходящему для цели региону.
        /// </summary>
        /// <param name="region">Регион, по которому кликнули.</param>
        public virtual void ClickAcceptedRegion(Region region) {
            UseAction(region);
        }

        /// <summary>
        /// Получает аргументы цели.
        /// </summary>
        public virtual TargetArgs GetArgs(Region region) {
            return new TargetArgs(Request.Player, Request.Caster);
        }

        /// <summary>
        /// Обработчик цели по умолчанию.
        /// </summary>
        public void UseAction(Region region) {
            Request.Execute(GetArgs(region));
        }
    }
}
